Research
Security News
Threat Actor Exposes Playbook for Exploiting npm to Build Blockchain-Powered Botnets
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
Lazy Object Streaming Pipeline for JavaScript - inspired by the Java 8 Streams API
Lazy Object Streaming Pipeline for JavaScript - inspired by the Java 8 Streams API
Stream(people)
.filter({age: 23})
.flatMap("children")
.map("firstName")
.distinct()
.filter(/a.*/i)
.join(", ");
Follow on Twitter for Updates
Stream.js is a lightweight (2.6 KB minified, gzipped), intensely tested (700+ assertions, 97% coverage) functional programming library for operating upon collections of in-memory data. It requires EcmaScript 5+, has built-in support for ES6 features and works in all current browsers, Node.js and Java 8 Nashorn.
Download the latest release from GitHub or install Stream.js via NPM or Bower:
npm install streamjs
# or
bower install streamjs
Read the APIDOC
Before explaining how Stream.js works in detail, here's a few real world code samples.
Filter and sort a collection of persons, then group everything by age.
Stream(people)
.filter({married: true, gender: 'male'})
.sorted("lastName");
.groupBy("age");
Filter and transform a collection of tweets to its text content, then limit the tweets to a maximum of 100 and partition the results into 10 tweets per page:
Stream(tweets)
.filter(function (tweet) {
return tweet.author !== me;
})
.map("text")
.filter(/.*streamjs.*/i)
.limit(100)
.partitionBy(10);
Create an array of 100 odd random numbers between 1 and 1000:
Stream
.generate(function() {
return Math.floor(Math.random() * 1000) + 1;
})
.filter(function (num) {
return num % 2 === 1;
})
.limit(100);
.toArray();
Create an infinite iterator, generating an odd random number between 1 and 1000 on each call to next()
:
var iterator = Stream
.generate(function() {
return Math.floor(Math.random() * 1000) + 1;
})
.filter(function (num) {
return num % 2 === 1;
})
.iterator();
iterator.next();
iterator.next();
Create an array of 100 parent objects, each holding an array of 10 children:
Stream
.range(0, 100)
.map(function (num) {
return {
parentId: num,
type: 'parent',
children: []
};
})
.peek(function (parent) {
parent.children = Stream
.range(0, 10)
.map(function (num) {
return {
childId: num,
type: 'child',
parent: parent
};
})
.toArray();
})
.toArray();
Stream.js defines a single function Stream
to create new streams from different input collections like arrays, maps or number ranges:
Stream([1, 2, 3]);
Stream({a: 1, b: 2, c: 3});
Stream.of(1, 2, 3);
Stream.range(1, 4);
Streams are monadic types with a bunch of useful operations. Those functions can be chained one after another to make complex computations upon the input elements. Operations are either intermediate or terminal. Intermediate operations are lazy and return the stream itself to enable method chaining. Terminal operations return a single result (or nothing at all). Some terminal operations return a special monadic Optional
type which is described later.
Streams are not limited to finite data sources like collections. You can also create infinite streams of elements by utilizing generator or iterator functions.
Stream.generate(function() {
return 1337 * Math.random();
);
Stream.iterate(1, function (seed) {
return seed * 2;
});
What's so different between Stream.js and other functional libraries like Underscore.js?
Stream.js is built around a lazily evaluated operation pipeline. Instead of consecutively performing each operation on the whole input collection, objects are passed vertically and one by one upon the chain. Interim results will not be stored in internal collections (except for some stateful operations like sorted
). Instead objects are directly piped into the resulting object as specified by the terminal operation. This results in minimized memory consumption and internal state.
Stream operations are lazily evaluated to avoid examining all of the input data when it's not necessary. Streams always perform the minimal amount of operations to gain results. E.g. in a filter - map - findFirst
stream you don't have to filter and map the whole data. Instead map
and findFirst
are executed just one time before returning the single result. This results in increased performance when operation upon large amounts of input elements.
Stream([1, 2, 3, 4])
.filter(function(num) { // called twice
return num % 2 === 0;
})
.map(function(even) { // called once
return "even" + even;
})
.findFirst(); // called once
The Stream.js API is described in detail here. For more information about Java 8 Streams I recommend reading the official Javadoc and this blog post.
A type definition for using Stream.js with Typescript is available here.
Found a bug or missing feature? Please open an issue! Your feedback and help is highly appreciated. Please refer to the contributing rules before sending a pull request. I would also love to hear your feedback via Twitter.
Created and copyright (c) 2014-2015 by Benjamin Winterberg.
Stream.js may be freely distributed under the MIT license.
FAQs
Lazy Object Streaming Pipeline for JavaScript - inspired by the Java 8 Streams API
We found that streamjs demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
Security News
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Security News
Research
A malicious npm package disguised as a WhatsApp client is exploiting authentication flows with a remote kill switch to exfiltrate data and destroy files.